/* 
 * Copyright [2018] [Alex/libo(liboms@hotmail.com)]
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.hyts.guava.exception;

import java.util.List;

import com.google.common.base.Optional;
import com.google.common.base.Throwables;
import com.hyts.guava.object.Objects;

/** 
 * @title ExceptionUtils.java  
 * @package com.hyts.guava.exception  
 * @description Exceptions guava操作处理异常信息构建服务类  
 * @see com.google.common.base.Throwables
 * @author libo/Alex
 * @email liboms@hotmail.com/liboware@163.com  
 * @date 2018年5月4日 
 * @version V1.0 
 */
public final class Exceptions {
	
	/**  
	 * <b>stackTraceToString</b>
	 * <p>打印堆栈里面的错误信息</p>
	 * @param throwable
	 * @return String
	 * @exception
	 */ 
	public static String stackTraceToString(Throwable throwable){
		//校验一下是否为空!直接快速失败方式报错
		Optional.of(throwable);
		return Throwables.getStackTraceAsString(throwable);
	}
	
	/**  
	 * <b>getThrowable</b>
	 * <p>打印堆栈里面的错误信息</p>
	 * @param throwable 打印堆栈信息错误信息
	 * @param index 索引 如果存在多个堆栈异常信息可以进行打印对应位置的(index)的堆栈
	 * @return  String
	 * @exception
	 */ 
	public static Throwable getThrowable(Throwable throwable,int index){
		Optional.of(throwable);
		return Throwables.getCausalChain(throwable).get(index);
	}
	
	
	/**  
	 * <b>getThrowables</b>
	 * <p>获取异常堆栈中所有的信息列表</p>
	 * @param throwable
	 * @return
	 * @exception
	 */ 
	public static List<Throwable> getThrowables(Throwable throwable){
		Optional.of(throwable);
		return Throwables.getCausalChain(throwable);
	}
	
	
	/**  
	 * <b>getThrowablesString</b>
	 * <p>获取异常堆栈中所有的信息列表并且转为字符串</p>
	 * @param throwable
	 * @return
	 * @exception
	 */ 
	public static String getThrowablesString(Throwable throwable){
		Optional.of(throwable);
		StringBuilder sb = new StringBuilder();
		Throwables.getCausalChain(throwable).forEach(exception->{
			sb.append(stackTraceToString(exception)).append("\n");
		});
		return sb.toString();
	}
	
	/**  
	 * <b>getThrowableString</b>
	 * <p>打印堆栈里面的错误信息 通过字符串信息</p>
	 * @param throwable 打印堆栈信息错误信息
	 * @param index 索引 如果存在多个堆栈异常信息可以进行打印对应位置的(index)的堆栈
	 * @return String
	 */ 
	public static String getThrowableString(Throwable throwable,int index){
		return stackTraceToString(getThrowable(throwable,index));
	}
	
	/**  
	 * <b>getFirstThrowable</b>
	 * <p>打印堆栈里面的错误信息</p>
	 * @param throwable
	 * @param index
	 * @return
	 * @exception
	 */ 
	public static Throwable getFirstThrowable(Throwable throwable,int index){
		Optional.of(throwable);
		return Throwables.getRootCause(throwable);
	}
	
	/**  
	 * <b>throwable</b>
	 * <p>打印堆栈里面的错误信息 通过字符串信息</p>
	 * @param throwable
	 * @param index
	 * @return
	 * @exception
	 */ 
	public static String getFirstThrowableString(Throwable throwable,int index){
		Optional.of(throwable);
		return stackTraceToString(Throwables.getRootCause(throwable));
	}
	
	/**  
	 * <b>throwRuntimeException:转换运行时异常</b>
	 * <p>转换运行时异常的字符串堆栈信息</p>
	 * @param throwable 
	 * @return RuntimeException
	 */ 
	public static RuntimeException throwRuntimeException(Throwable throwable){
		Optional.of(throwable);
		return Throwables.propagate(throwable);
	}
	
	/**  
	 * <b>throwRuntimeExceptionString:转换运行时异常的字符串堆栈信息</b>
	 * <p>转换运行时异常的字符串堆栈信息</p>
	 * @param throwable
	 * @return 异常堆栈信息字符串
	 */ 
	public static String throwRuntimeExceptionString(Throwable throwable){
		Optional.of(throwable);
		return stackTraceToString(Throwables.propagate(throwable));
	}
	
}
